// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#include <pollux/testing/flags.h>

TURBO_FLAG(bool,
           file_system_error_injection,
           true,
           "When enabled, inject file system write error with certain possibility");

TURBO_FLAG(int32_t, steps, 10, "Number of plans to generate and test.");

TURBO_FLAG(int32_t,
           duration_sec,
           0,
           "For how long it should run (in seconds). If zero, "
           "it executes exactly --steps iterations and exits.");

TURBO_FLAG(int32_t,
           batch_size,
           100,
           "The number of elements on each generated vector.");

TURBO_FLAG(int32_t, num_batches, 10, "The number of generated vectors.");

TURBO_FLAG(double,
           null_ratio,
           0.1,
           "Chance of adding a null value in a vector "
           "(expressed as double from 0 to 1).");

TURBO_FLAG(bool, enable_window_reference_verification,
           false,
           "When true, the results of the window aggregation are compared to reference DB results");


TURBO_FLAG(bool, enable_spill, true, "Whether to test plans with spilling enabled");

TURBO_FLAG(bool,
           enable_oom_injection,
           false,
           "When enabled OOMs will randomly be triggered while executing query "
           "plans. The goal of this mode is to ensure unexpected exceptions "
           "aren't thrown and the process isn't killed in the process of cleaning "
           "up after failures. Therefore, results are not compared when this is "
           "enabled. Note that this option only works in debug builds.");

TURBO_FLAG(double,
           filter_ratio,
           0,
           "The chance of testing plans with filters enabled.");


TURBO_FLAG(int32_t, max_error_rows, 10, "Max number of listed error rows");


TURBO_FLAG(int32_t, num_threads, 16, "Number of read threads.");

TURBO_FLAG(int32_t,
           read_iteration_sec,
           10,
           "For how long each read thread should run (in seconds).");

TURBO_FLAG(int32_t, num_source_files, 8, "Number of data files to be created.");

TURBO_FLAG(int64_t,
           source_file_bytes,
           -1,
           "Source file size in bytes. When set to -1, a random value from 32MB to 48MB will be used, inclusively.");

TURBO_FLAG(int64_t,
           memory_cache_bytes,
           -1,
           "Memory cache size in bytes. When set to -1, a random value from 48 to 64MB will be used, inclusively.");

TURBO_FLAG(int64_t,
           ssd_cache_bytes,
           -1,
           "SSD cache size in bytes. When set to -1, 1 out of 10 times SSD cache will be disabled, "
           "while the other times, a random value from 128MB to 256MB will be used, inclusively.");

TURBO_FLAG(int32_t,
           num_ssd_cache_shards,
           -1,
           "Number of SSD cache shards. When set to -1, a random value from 1 to 4 will be used, inclusively.");

TURBO_DECLARE_FLAG(bool, pollux_ssd_odirect);

TURBO_FLAG(int64_t,
           ssd_checkpoint_interval_bytes,
           -1,
           "Checkpoint after every 'ssd_checkpoint_interval_bytes'/'num_ssd_cache_shards', written into "
           "each file. 0 means no checkpointing. When set to -1, 1 out of 4 times checkpoint will be disabled, "
           "while the other times, a random value from 32MB to 64MB will be used, inclusively.");

TURBO_FLAG(int32_t, num_restarts, 3, "Number of cache restarts in one iteration.");

TURBO_FLAG(bool,
           enable_file_faulty_injection,
           true,
           "Enable fault injection on read and write operations for cache-related files. When enabled, "
           "the file read and write operations will fail 5 out of 100 times.");

TURBO_FLAG(bool,
           enable_sorted_aggregations,
           true,
           "When true, generates plans with aggregations over sorted inputs");


TURBO_FLAG(int32_t,
           max_num_varargs,
           5,
           "The maximum number of variadic arguments fuzzer will generate for "
           "functions that accept variadic arguments. Fuzzer will generate up to "
           "max_num_varargs arguments for the variadic list in addition to the "
           "required arguments by the function.");


TURBO_FLAG(std::string,
           repro_persist_path,
           "",
           "Directory path for persistence of data and SQL when fuzzer fails for "
           "future reproduction. Empty string disables this feature.");

TURBO_FLAG(bool,
           persist_and_run_once,
           false,
           "Persist repro info before evaluation and only run one iteration. "
           "This is to rerun with the seed number and persist repro info upon a "
           "crash failure. Only effective if repro_persist_path is set.");

TURBO_FLAG(bool,
           log_signature_stats,
           false,
           "Log statistics about function signatures");
TURBO_FLAG(int32_t, timing_repeats, 0, "Count of repeats for timing filter tests");


TURBO_FLAG(int32_t,
           iteration_duration_sec,
           10,
           "For how long it should run (in seconds) per iteration.");

TURBO_FLAG(int64_t, arbitrator_capacity, 256L << 20, "Arbitrator capacity in bytes.");

TURBO_FLAG(int32_t,
           global_arbitration_pct,
           5,
           "Each second, the percentage chance of triggering global arbitration by "
           "calling shrinking pools globally.");

TURBO_FLAG(double,
           spill_faulty_fs_ratio,
           0.1,
           "Chance of spill filesystem being faulty(expressed as double from 0 to 1)");

TURBO_FLAG(int32_t,
           spill_fs_fault_injection_ratio,
           0.01,
           "The chance of actually injecting fault in file operations for spill "
           "filesystem. This is only applicable when 'spill_faulty_fs_ratio' is "
           "larger than 0");

TURBO_FLAG(int32_t,
           task_abort_interval_ms,
           1000,
           "After each specified number of milliseconds, abort a random task."
           "If given 0, no task will be aborted.");


TURBO_FLAG(bool,
           retry_with_try,
           false,
           "Retry failed expressions by wrapping it using a try() statement.");

TURBO_FLAG(bool,
           find_minimal_subexpression,
           false,
           "Automatically seeks minimum failed subexpression on result mismatch");

TURBO_FLAG(bool,
           disable_constant_folding,
           false,
           "Disable constant-folding in the common evaluation path.");


TURBO_FLAG(double,
           lazy_vector_generation_ratio,
           0.0,
           "Specifies the probability with which columns in the input row "
           "vector will be selected to be wrapped in lazy encoding "
           "(expressed as double from 0 to 1).");

TURBO_FLAG(double,
           common_dictionary_wraps_generation_ratio,
           0.0,
           "Specifies the probability with which columns in the input row "
           "vector will be selected to be wrapped in a common dictionary wrap "
           "(expressed as double from 0 to 1). Only columns not already encoded "
           "will be considered.");

TURBO_FLAG(int32_t,
           max_expression_trees_per_step,
           1,
           "This sets an upper limit on the number of expression trees to generate "
           "per step. These trees would be executed in the same ExprSet and can "
           "re-use already generated columns and subexpressions (if re-use is "
           "enabled).");

// The flags bellow are used to initialize ExpressionFuzzer::options.
TURBO_FLAG(std::string,
           only,
           "",
           "If specified, Fuzzer will only choose functions from "
           "this comma separated list of function names "
           "(e.g: --only \"split\" or --only \"substr,ltrim\").");

TURBO_FLAG(std::string,
           special_forms,
           "and,or,cast,coalesce,if,switch",
           "Comma-separated list of special forms to use in generated expression. "
           "Supported special forms: and, or, coalesce, if, switch, cast.");

TURBO_FLAG(int32_t,
           pollux_fuzzer_max_level_of_nesting,
           10,
           "Max levels of expression nesting. The default value is 10 and minimum is 1.");


TURBO_FLAG(bool,
           enable_variadic_signatures,
           false,
           "Enable testing of function signatures with variadic arguments.");

TURBO_FLAG(bool,
           enable_dereference,
           false,
           "Allow fuzzer to generate random expressions with dereference and row_constructor functions.");

TURBO_FLAG(bool,
           pollux_fuzzer_enable_complex_types,
           false,
           "Enable testing of function signatures with complex argument or return types.");

TURBO_FLAG(bool,
           pollux_fuzzer_enable_decimal_type,
           false,
           "Enable testing of function signatures with decimal argument or return types.");

TURBO_FLAG(bool,
           pollux_fuzzer_enable_column_reuse,
           false,
           "Enable generation of expressions where one input column can be "
           "used by multiple subexpressions");

TURBO_FLAG(bool,
           pollux_fuzzer_enable_expression_reuse,
           false,
           "Enable generation of expressions that re-uses already generated "
           "subexpressions.");

TURBO_FLAG(std::string,
           assign_function_tickets,
           "",
           "Comma separated list of function names and their tickets in the format "
           "<function_name>=<tickets>. Every ticket represents an opportunity for "
           "a function to be chosen from a pool of candidates. By default, "
           "every function has one ticket, and the likelihood of a function "
           "being picked can be increased by allotting it more tickets. Note "
           "that in practice, increasing the number of tickets does not "
           "proportionally increase the likelihood of selection, as the selection "
           "process involves filtering the pool of candidates by a required "
           "return type so not all functions may compete against the same number "
           "of functions at every instance. Number of tickets must be a positive "
           "integer. Example: eq=3,floor=5");

//////////////////


TURBO_FLAG(int32_t,
           max_spill_level,
           -1,
           "Max spill level, -1 means random [0, 7], otherwise the actual level.");
